<template>
	<div class="ele-body">
		<el-card shadow="never">
			<!-- 搜索表单 -->
			<el-form :model="where" label-width="77px" class="ele-form-search" @keyup.enter.native="query" @submit.native.prevent>
				<el-row :gutter="15">
					<el-col :md="5" :sm="12">
						<el-form-item label="菜单名称:"><el-input v-model="where.title" placeholder="请输入" clearable /></el-form-item>
					</el-col>
					<el-col :md="5" :sm="12">
						<el-form-item label="菜单地址:"><el-input v-model="where.path" placeholder="请输入" clearable /></el-form-item>
					</el-col>
					<el-col :md="10" :sm="12">
						<div class="ele-form-actions">
							<el-button type="primary" @click="query" icon="el-icon-search" class="ele-btn-icon">查询</el-button>
							<el-button @click="add()" type="primary" icon="el-icon-plus" class="ele-btn-icon">添加</el-button>
							<el-button @click="expandAll" class="ele-btn-icon">展开全部</el-button>
							<el-button @click="foldAll" class="ele-btn-icon">折叠全部</el-button>
						</div>
					</el-col>
				</el-row>
			</el-form>
			<!-- 数据表格 -->
			<el-table ref="table" :data="data" v-loading="loading" row-key="menuId" default-expand-all border height="calc(100vh - 211px)" highlight-current-row>
				<el-table-column type="index" width="45" align="center" fixed="left" />
				<el-table-column label="菜单名称" show-overflow-tooltip min-width="110">
					<template slot-scope="{ row }">
						<i :class="row.icon" />
						{{ row.title }}
					</template>
				</el-table-column>
				<el-table-column prop="path" label="路由地址" show-overflow-tooltip min-width="110" />
				<el-table-column prop="component" label="组件路径" show-overflow-tooltip min-width="110" />
				<el-table-column prop="authority" label="权限标识" show-overflow-tooltip min-width="110" />
				<el-table-column prop="sortNumber" label="排序" width="60px" align="center" />
				<el-table-column label="隐藏" width="60px" align="center">
					<template slot-scope="{ row }">
						{{ ['否', '是'][row.hide] }}
					</template>
				</el-table-column>
				<el-table-column label="类型" width="60px" align="center">
					<template slot-scope="{ row }">
						<el-tag :type="['primary', 'info'][row.menuType]" size="mini">{{ ['菜单', '按钮'][row.menuType] }}</el-tag>
					</template>
				</el-table-column>
				<el-table-column label="创建时间" show-overflow-tooltip min-width="100" align="center">
					<template slot-scope="{ row }">
						{{ row.createTime | toDateString }}
					</template>
				</el-table-column>
				<el-table-column label="操作" width="190px" align="center" :resizable="false">
					<template slot-scope="{ row }">
						<el-link @click="add(row)" icon="el-icon-plus" type="primary" :underline="false">添加</el-link>
						<el-link @click="edit(row)" icon="el-icon-edit" type="primary" :underline="false">修改</el-link>
						<el-popconfirm title="确定要删除吗？" @confirm="remove(row)" class="ele-action">
							<el-link slot="reference" icon="el-icon-delete" type="danger" :underline="false">删除</el-link>
						</el-popconfirm>
					</template>
				</el-table-column>
			</el-table>
		</el-card>
		<!-- 编辑弹窗 -->
		<el-dialog
			:title="form.menuId ? '修改菜单' : '添加菜单'"
			:visible.sync="showEdit"
			width="600px"
			@closed="form = {}"
			:destroy-on-close="true"
			custom-class="ele-dialog-form"
			:lock-scroll="false"
			:close-on-click-modal="false"
		>
			<el-form :model="form" ref="editForm" :rules="rules" label-width="82px" @keyup.enter.native="save" @submit.native.prevent>
				<el-row :gutter="15">
					<el-col :sm="12">
						<el-form-item label="上级菜单:">
							<treeselect
								v-model="form.parentId"
								:options="data"
								placeholder="请选择上级菜单"
								:defaultExpandLevel="1"
								:normalizer="
									d => {
										return { id: d.menuId, label: d.title, children: d.children || undefined };
									}
								"
							/>
						</el-form-item>
						<el-form-item label="菜单名称:" prop="title"><el-input v-model="form.title" placeholder="请输入菜单名称" clearable /></el-form-item>
						<el-form-item label="菜单图标:"><ele-icon-picker v-model="form.icon" placeholder="请选择菜单图标" /></el-form-item>
						<el-form-item label="路由地址:"><el-input v-model="form.path" placeholder="请输入路由地址" clearable /></el-form-item>
						<el-form-item label="组件路径:"><el-input v-model="form.component" placeholder="请输入组件路径" clearable /></el-form-item>
					</el-col>
					<el-col :sm="12">
						<el-form-item label="权限标识:"><el-input v-model="form.authority" placeholder="请输入权限标识" clearable /></el-form-item>
						<el-form-item label="排序号:" prop="sortNumber">
							<el-input-number v-model="form.sortNumber" controls-position="right" :min="0" placeholder="请输入排序号" class="ele-fluid ele-text-left" />
						</el-form-item>
						<el-form-item label="菜单类型:">
							<el-radio-group v-model="form.menuType">
								<el-radio :label="0">菜单</el-radio>
								<el-radio :label="1">按钮</el-radio>
							</el-radio-group>
						</el-form-item>
						<el-form-item label="是否隐藏:">
							<el-radio-group v-model="form.hide">
								<el-radio :label="0">显示</el-radio>
								<el-radio :label="1">隐藏</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<div slot="footer">
				<el-button @click="showEdit = false">取消</el-button>
				&nbsp;
				<el-button type="primary" @click="save">保存</el-button>
			</div>
		</el-dialog>
	</div>
</template>

<script>
import Treeselect from '@riophae/vue-treeselect'; // 下拉树
import '@riophae/vue-treeselect/dist/vue-treeselect.css';

export default {
	name: 'SysMenu',
	components: { Treeselect },
	data() {
		return {
			loading: true, // 加载状态
			data: [], // 列表数据
			where: {}, // 搜索条件
			showEdit: false, // 是否显示表单弹窗
			form: {}, // 表单数据
			rules: {
				// 表单验证规则
				title: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
				sortNumber: [{ required: true, message: '请输入排序号', trigger: 'blur' }]
			}
		};
	},
	mounted() {
		this.query();
	},
	methods: {
		/* 查询 */
		query() {
			this.loading = true;
			this.$http
				.get('/sys/menu/list', { params: this.where })
				.then(res => {
					this.loading = false;
					if (res.data.code === 0) {
						this.data = this.$util.toTreeData(res.data.data, 'menuId', 'parentId');
					} else {
						this.$message.error(res.data.msg || '获取数据失败');
					}
				})
				.catch(e => {
					this.loading = false;
					this.$message.error(e.message);
				});
		},
		/* 显示添加 */
		add(row) {
			this.form = { menuType: 0, hide: 0, parentId: row ? row.menuId : null };
			this.showEdit = true;
		},
		/* 显示编辑 */
		edit(row) {
			this.form = Object.assign({}, row, { parentId: row.parentId || null });
			this.showEdit = true;
		},
		/* 保存编辑 */
		save() {
			const posturl = this.form.menuId ? '/sys/menu/update' : '/sys/menu/add';
			this.$refs['editForm'].validate(valid => {
				if (valid) {
					const loading = this.$loading({ lock: true });
					this.$http
						.post(posturl, Object.assign({}, this.form, { parentId: this.form.parentId || 0 }))
						.then(res => {
							loading.close();
							if (res.data.code === 0) {
								this.showEdit = false;
								this.$message({ type: 'success', message: res.data.msg });
								if (this.form.menuId) {
									// 更新数据
									this.$util.eachTreeData(this.data, item => {
										if (item.menuId === this.form.menuId) {
											Object.assign(item, this.form);
											return false;
										}
									});
								} else {
									this.query();
								}
							} else {
								this.$message.error(res.data.msg);
							}
						})
						.catch(e => {
							loading.close();
							this.$message.error(e.message);
						});
				} else {
					return false;
				}
			});
		},
		/* 删除 */
		remove(row) {
			if (row.children && row.children.length > 0) return this.$message.error('请先删除子节点');
			const loading = this.$loading({ lock: true });
			this.$http
				.post('/sys/menu/remove?id=' + row.menuId)
				.then(res => {
					loading.close();
					if (res.data.code === 0) {
						this.$message({ type: 'success', message: res.data.msg });
						// 删除数据
						this.$util.eachTreeData(this.data, item => {
							if (item.menuId === row.parentId) {
								item.children.splice(item.children.findIndex(d => d.menuId === row.menuId), 1);
								return false;
							}
						});
					} else {
						this.$message.error(res.data.msg);
					}
				})
				.catch(e => {
					loading.close();
					this.$message.error(e.message);
				});
		},
		expandAll() {
			this.data.forEach(d => {
				this.$refs.table.toggleRowExpansion(d, true);
			});
		},
		foldAll() {
			this.data.forEach(d => {
				this.$refs.table.toggleRowExpansion(d, false);
			});
		}
	}
};
</script>

<style scoped></style>
